﻿
#if WinRT
    using Windows.UI.Xaml;
#else
using System.Windows;
#endif


namespace DailyFx.UI
{
	public static class ActionProps
	{
		static readonly ILog Log = LogManager.GetLog( typeof(ActionProps) );


		public static readonly DependencyProperty TargetProperty = DependencyProperty.RegisterAttached
			( "Target", typeof(object), typeof( ActionProps), new PropertyMetadata(null, TargetChanged) );

		public static readonly DependencyProperty UncontextTargetProperty = DependencyProperty.RegisterAttached
			( "UncontextTarget", typeof(object), typeof(ActionProps), new PropertyMetadata(null, UncontextTargetChanged) );

        /// <summary>
        ///   Sets the target of the <see cref="MessageAction" /> .
        /// </summary>
        public static void SetTarget( DependencyObject dependency, object target)
		{
            dependency.SetValue( TargetProperty, target );
        }

        /// <summary>
        ///   Gets the target for <see cref="MessageAction" /> .
        /// </summary>
        public static object GetTarget ( DependencyObject dependency ) 
		{
            return dependency.GetValue( TargetProperty );
        }
		 /// <summary>
        ///		Sets the target of the <see cref="MessageAction" /> .
        /// </summary>
        /// <remarks>
        ///		The DataContext of ui element will not be set to this .
        /// </remarks>
        public static void SetUncontextTarget ( DependencyObject dependency, object target)
		{
			dependency.SetValue( UncontextTargetProperty, target);
        }

        /// <summary>
        ///		Gets the target for instances of <see cref="MessageAction" /> .
        /// </summary>
		public static object GetUncontextTarget ( DependencyObject dependency )
		{
			return dependency.GetValue( UncontextTargetProperty );
        }

        ///<summary>
        ///		Checks if the <see cref="MessageAction" /> -Target was set.
        ///</summary>
        public static bool HasTarget ( DependencyObject element ) 
		{
            if ( GetTarget(element) != null || GetUncontextTarget (element) != null )
                return true;

            var frameworkElement = element as FrameworkElement;
            if (frameworkElement == null)
                return false;

            return ConventionManager.HasBinding( frameworkElement, TargetProperty ) ||
				ConventionManager.HasBinding( frameworkElement, UncontextTargetProperty );
        }

		static void TargetChanged ( DependencyObject d, DependencyPropertyChangedEventArgs e )
		{
			SetTargetImpl (d, e, true);
		}

		static void UncontextTargetChanged ( DependencyObject d, DependencyPropertyChangedEventArgs e )
		{
			SetTargetImpl (d, e, false);
		}

		static void SetTargetImpl ( DependencyObject d, DependencyPropertyChangedEventArgs e, bool context )
		{
			if (e.NewValue == e.OldValue)
			{
				return;
			}
			var target = e.NewValue;
			var key = e.NewValue as string;
			if (key != null)
			{
				target = IoC.DoGet( null, key );
			}

			if ( context && d is FrameworkElement )
			{
				( (FrameworkElement)d ).DataContext = target;
				Log.Info("Setting DC of {0} to {1}.", d, target);
			}

			MsgProps.SetHandler( d, target );
			Log.Info("Attaching message handler {0} to {1}.", target, d );
		}
	}

}